package com.tian.service.impl;

import com.alibaba.fastjson.JSON;
import com.tian.common.CommonResult;
import com.tian.dto.exchange.CheckExchangeCodeReqDto;
import com.tian.dto.exchange.CheckExchangeCodeRespDto;
import com.tian.dto.exchange.ExchangeCodeDto;
import com.tian.entity.ExchangeCode;
import com.tian.enums.ExchangeCodeStatusEnum;
import com.tian.exception.BusinessException;
import com.tian.mapper.ExchangeCodeMapper;
import com.tian.service.ExchangeCodeValidateService;
import com.tian.util.CodeUtil;
import com.tian.util.RedisConstantPre;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.Objects;

/**
 * {@code @description:} 兑换码验证加强版接口
 *
 * @author tianwc 公众号：Java后端技术全栈
 * 在线刷题 1200+java面试题和1000+篇技术文章：<a href="https://woaijava.cc/">博客地址</a>
 * {@code @date:} 2024-11-24 19:52
 * {@code @version:} 1.0
 */
@Service("exchangeCodeValidateDecoratorService")
public class ExchangeCodeValidateDecoratorServiceImpl implements ExchangeCodeValidateService {
    @Resource
    private ExchangeCodeMapper exchangeCodeMapper;
    @Resource
    private RedissonClient redissonClient;
    @Resource
    private ExchangeCodeValidateService exchangeCodeValidateService;

    @Override
    public CommonResult<CheckExchangeCodeRespDto> validateCode(CheckExchangeCodeReqDto checkExchangeCodeReqDto) {
        String code = checkExchangeCodeReqDto.getCode();
        // 校验兑换码格式
        if (!CodeUtil.validateCode(code)) {
            return CommonResult.failed("兑换码格式不正确！");
        }
        RBucket<Object> bucket = redissonClient.getBucket(RedisConstantPre.EXCHANGE_CODE_KEY + code);
        ExchangeCodeDto exchangeCodeDto = JSON.parseObject(bucket.get().toString(), ExchangeCodeDto.class);
        if (exchangeCodeDto == null) {
            ExchangeCode exchangeCode = exchangeCodeMapper.selectByCode(code);
            if (exchangeCode == null) {
                // 兑换码不存在，设置空缓存（避免恶意攻击 缓存数据库都不存在的情况）
                bucket.set(JSON.toJSONString(new ExchangeCodeDto()));
            }
            return CommonResult.failed("兑换码不存在！");
        }

        if (exchangeCodeDto.getStatus() == null) {
            return CommonResult.failed("兑换码不存在！");
        }
        ExchangeCode exchangeCode = exchangeCodeMapper.selectByCode(code);
        if (exchangeCode == null) {
            return CommonResult.failed("兑换码不存在！");
        }
        if (Objects.equals(exchangeCode.getStatus(), ExchangeCodeStatusEnum.USED.getCode())) {
            throw new BusinessException("兑换码已使用");
        }
        if (Objects.equals(exchangeCode.getStatus(), ExchangeCodeStatusEnum.USING.getCode())) {
            throw new BusinessException("兑换码正在使用");
        }
        if (Objects.equals(exchangeCode.getStatus(), ExchangeCodeStatusEnum.EXPIRED.getCode())) {
            throw new BusinessException("兑换码已过期");
        }
        if (exchangeCode.getExpiredTime().before(new Date())) {
            return CommonResult.failed("兑换码已过期！");
        }
        if (checkExchangeCodeReqDto.getAmount() == null) {
            return CommonResult.success();
        }
        checkExchangeCodeReqDto.setCouponId(exchangeCode.getCouponId());
        return exchangeCodeValidateService.validateCode(checkExchangeCodeReqDto);
    }
}
